package com.njbw.rateLimit;

import java.util.Random;
import java.util.concurrent.ArrayBlockingQueue;

/**
 * 令牌桶算法
 *
 * @author 黄侯淳
 * @since JDK 1.8
 */
public class Token {

    // 添加令牌速率 1s 10个
    private int rate = 10;

    // 漏桶
    private ArrayBlockingQueue<Object> bucket;

    public Token(int rate, int capacity) {
        this.rate = rate;
        this.bucket = new ArrayBlockingQueue(capacity);
        //恒定速率往漏桶里面添加令牌
        int speed = 1000 / this.rate;
        new Thread(() -> {
            while (true) {
                bucket.offer(this);
                try {
                    Thread.sleep(speed);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    public boolean tryAcquire() {
        // 漏桶里面取令牌
        return null != bucket.poll();
    }


    public static void main(String[] args) throws InterruptedException {
        Token token = new Token(10, 100);
        // 8s 后突发流量
        Thread.sleep(8000);
        int count = 0;
        while (true) {
            if (token.tryAcquire())  {
                System.out.println(count ++ +"请求成功...");
            } else {
                System.out.println(count ++ +"限流了...");
            }
            Thread.sleep(20 * new Random().nextInt(5));
        }
    }
}
